<?php
declare(strict_types=1);

namespace lib\data\traits;

trait ComponentsTrait {
    protected static array $pk = [];
    protected static array $cate_cache = [];
    protected static array $goods_id_cache = [];

    public function traitInit(){
        static::$pk[$this->id] = $this;
        foreach($this->category_ids as $cateId){
            static::$cate_cache[$cateId][$this->id] = $this;
        }
        if(0 !== $this->goods_id){
            static::$goods_id_cache[$this->mid][$this->goods_id] = $this;
        }
    }


    public static function get(int $id) :?static{
        return static::$pk[$id]??null;
    }

    public static function getByCate(int $cateId) :array{
        return array_values(static::$cate_cache[$cateId]??[]);
    }

    public static function getByGoodsId(int $mid, int $goodsId) :?static{
        return static::$goods_id_cache[$mid][$goodsId]??null;
    }

    public function remove(){
        $mid = $this->mid;
        $id = $this->id;
        unset(static::$pk[$id]);
        foreach($this->category_ids as $cateId){
            unset(static::$cate_cache[$cateId][$id]);
        }
        if(0 !== $this->goods_id){
            unset(static::$goods_id_cache[$mid][$this->goods_id]);
            if(empty(static::$goods_id_cache[$mid])){
                static::$goods_id_cache[$mid] = [];
            }
        }
    }

    protected function onUpdate(array &$newvalue, array $oldvalue) :void {
        if(isset($newvalue['category_ids'])){
            // 使用 array_diff 来计算差集 获得要删除的分类和要新增的分类。然后更新索引
            $delCateIds = array_diff($oldvalue['category_ids'], $newvalue['category_ids']);
            $addCateIds = array_diff($newvalue['category_ids'], $oldvalue['category_ids']);
            foreach($delCateIds as $cateId){
                unset(static::$cate_cache[$cateId][$this->id]);
            }
            foreach($addCateIds as $cateId){
                static::$cate_cache[$cateId][$this->id] = $this;
            }
        }
        if(isset($newvalue['goods_id'])){
            if(0 !== $oldvalue['goods_id']){
                unset(static::$goods_id_cache[$this->mid][$oldvalue['goods_id']]);
            }
            if(0 !== $newvalue['goods_id']){
                static::$goods_id_cache[$this->mid][$newvalue['goods_id']] = $this;
            }
        }
    }
}